package A3GCConcreteTestCase;

import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import org.jgroups.Address;
import org.jgroups.JChannel;
import org.jgroups.Message;
import org.jgroups.View;
import org.jgroups.blocks.ReplicatedHashMap;

import A3GCPackage.SingleNodeData;

public class DebugNodePanel extends JTabbedPane
{
	private static final long serialVersionUID = 1L;

	private JChannel gcAccessChannel;
	private String   properties = null;
	private ReplicatedHashMap<String, SingleNodeData> nodeMap;
	protected final String gcChannel = "A3GCPackageChannel";

	private JTable                 hashDataTable;
	private Vector<String> 		   columns;
	private Vector<Vector<String>> rowData;

	private JTable                 viewDataTable;
	private Vector<String>         viewColumns;
	private Vector<Vector<String>> viewRowData;
	
	public DebugNodePanel()
	{
		columns = new Vector<String>();
		columns.add( "Name" );
		columns.add( "Active" );
		columns.add( "Decay" );
		columns.add( "Group Name" );
		columns.add( "Time Stamp" );
		columns.add( "Address" );
		
		rowData = new Vector<Vector<String>>();
		rowData.add( new Vector<String>(6) );
		rowData.get(0).add( "No Data" );
		rowData.get(0).add( "No Data" );
		rowData.get(0).add( "No Data" );
		rowData.get(0).add( "No Data" );
		rowData.get(0).add( "No Data" );
		rowData.get(0).add( "No Data" );
		
		hashDataTable = new JTable( rowData, columns );
		
		viewColumns = new Vector<String>();
		viewColumns.add( "Address" );
		
		viewRowData = new Vector<Vector<String>>();
		viewRowData.add( new Vector<String>(1) );
		viewRowData.get(0).add( "No Data" );
		
		viewDataTable = new JTable( viewRowData, viewColumns );
		
		try 
		{
			gcAccessChannel = new JChannel(properties);
			gcAccessChannel.setName("Debugger");
			nodeMap = new ReplicatedHashMap<String, SingleNodeData>( gcAccessChannel )
			{
				public void receive( Message m )
				{
					//System.out.println("\n\nGOT a receive in DebugNodePanel");
					if ( gcAccessChannel.getReceiver() != null )
						gcAccessChannel.getReceiver().receive(m);
					
					updateRows();
				}
				
				public void viewAccepted( View v )
				{
					//System.out.println("\n\nGot a viewAccepted call in DebugNodePanel");
					updateView( v );
					if ( gcAccessChannel.getReceiver() != null )
						gcAccessChannel.getReceiver().viewAccepted(v);
				}
			};
			
			gcAccessChannel.connect(gcChannel);
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		
		JScrollPane jsp;
		jsp = new JScrollPane( viewDataTable );
		addTab( "View Data", jsp );
		
		jsp = new JScrollPane( hashDataTable );
		addTab( "Node Data", jsp );
		
		TimerTask tt = new TimerTask() 
		{
			
			@Override
			public void run() 
			{
				//System.out.println("Updating rows");
				updateRows();
			}
		};
		
		Timer t = new Timer();
		
		t.schedule(tt, 1000, 1000);
	}
	
	public void updateView( View view )
	{
		viewRowData.clear();
		
		Iterator<Address> iter = view.iterator();
		//System.out.println("view members:");
		while ( iter.hasNext() )
		{
			Vector<String> temp = new Vector<String>(1);
			Address addr = iter.next();
			//System.out.println("next = " + addr.toString() );
			temp.add( addr.toString() );
			viewRowData.add( temp );
		}
		
		viewDataTable.setModel(new DefaultTableModel(viewRowData, viewColumns) );
	}
	
	public void updateRows()
	{
		Set<Entry<String, SingleNodeData>> set = nodeMap.entrySet();
		
		Iterator<Entry<String, SingleNodeData>> iter = set.iterator();
		
		rowData.clear();
		
		while ( iter.hasNext() )
		{
			Entry<String, SingleNodeData> ent = iter.next();
			SingleNodeData  snd = ent.getValue();
			
			Vector<String> temp = new Vector<String>(6);
			
			if ( snd == null )
			{
				temp.add( "No Data" );
				temp.add( "No Data" );
				temp.add( "No Data" );
				temp.add( "No Data" );
				temp.add( "No Data" );
				temp.add( "No Data" );
			}
			else
			{
				temp.add( snd.name );
				if ( snd.active )
					temp.add( "True" );
				else
					temp.add( "False" );
				temp.add( Integer.toString(snd.decay) );
				temp.add( snd.group );
				temp.add( snd.timestamp.toString() );
				temp.add( snd.address.toString() );
			}
			
			rowData.add( temp );
		}
		
		hashDataTable.setModel( new DefaultTableModel( rowData, columns ) );
	}
}
